﻿using System;
using System.Collections.Generic;
using DeHeng_Mes.Constant;
using S7.Net;
using System.Management;
using DeHeng_Mes.Model.PlcModel.P1;
using DeHeng_Mes.Model.PlcModel.P6;

namespace DeHeng_Mes.Utils
{
    public static class MappingTable
    {
        /// <summary>
        /// plc数据与实体类的映射
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="plcName"></param>
        /// <returns></returns>
        public static Dictionary<object, Type> PlcMapping(Plc plc, string plcName)
        {
            // 初始化返回值
            Dictionary<object, Type> dic = new Dictionary<object, Type>();

            // 定义一个类型和地址的映射表
            var typeAddressMap = new Dictionary<string, List<(Type type, int address)>>
            {
                { "P6", new List<(Type, int)>
                    {
                        (typeof(P6Power), 6002),
                        //(typeof(P6Production), 6001),
                        (typeof(P6Code), 5060),
                        (typeof(P6Check), 5061),
                    }
                },
            };

            // 定义读取数据并添加到字典的方法
            void AddInstance(Type type, int address)
            {
                // 引用ReadClass方法的命名空间和类
                var method = typeof(Plc).GetMethod("ReadClass", new Type[] { typeof(int), typeof(int) })?.MakeGenericMethod(type);
                var instance = method.Invoke(plc, new object[] { address, 0 });
                dic.Add(instance, type);
            }

            try
            {
                // 检查并处理对应的Name类型
                if (typeAddressMap.ContainsKey(plcName))
                {
                    foreach (var (type, address) in typeAddressMap[plcName])
                    {
                        AddInstance(type, address);
                    }
                }

                return dic;
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"{plcName}获取Plc数据实例与实例类型映射失败，原因是：" + ex.Message);
            }

            return dic;
        }

        /// <summary>
        /// 获取Cpu唯一标识
        /// </summary>
        public static string DeviceIdentifier()
        {
            string cpuId = string.Empty;
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select ProcessorId from Win32_Processor"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    cpuId = obj["ProcessorId"].ToString();
                    break;
                }
            }
            return cpuId;
        }

        /// <summary>
        /// 设备与数据库账号映射表
        /// </summary>
        /// <param name="cpuIp"></param>
        /// <returns></returns>
        public static (string, string) GetSqlUser(string cpuIp)
        {
            string userName = "";
            string passWord = "";
            //BFEBFBFF000906EA
            //BFEBFBFF000906EA
            Dictionary<string, Dictionary<string, string>> dic = new Dictionary<string, Dictionary<string, string>>()
            {
                {"178BFBFF00A70F52",new Dictionary<string, string>()
                {
                    { "sa","yk19991223"}
                } },
                {"BFEBFBFF000806EB",new Dictionary<string, string>()
                {
                    { "root","265422"}
                } }
            };

            foreach (var item in dic)
            {
                if (item.Key.Equals(cpuIp))
                {
                    //解析Value
                    foreach (var item1 in item.Value)
                    {
                        userName = item1.Key;
                        passWord = item1.Value;
                    }
                }
            }


            return (userName, passWord);
        }

        /// <summary>
        /// 请求对照表
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string UrlAnalysis(string url)
        {
            Dictionary<string, string> dic
                = new Dictionary<string, string>()
                {
                    {"OrderInfo","ProcessRequest" },
                    {"ISVGlue","ISVGlue" },
                    {"ISVWeld","ISVWeld" },
                    {"receiveReport","receiveReport" },
                };
            foreach (var item in dic)
            {
                if (url.Contains(item.Key))
                {
                    return item.Value;
                }
            }
            return "";
        }

        /// <summary>
        /// 获取该类字段与Plc数据映射
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static List<string> GetDicByName(string key)
        {
            var dic = new Dictionary<string, List<string>>();

            #region 状态读取映射
            dic["P6-STATUS"] = new List<string>()
            {
                SystemConstant.OP10,
                SystemConstant.OP20,
                SystemConstant.OP25,
                SystemConstant.OP30,
                SystemConstant.OP40,
                SystemConstant.NgStation
            };
            #endregion

            // 返回匹配数据
            if (dic.TryGetValue(key, out List<string> data))
                return data;

            return null;
        }

        /// <summary>
        /// 获取返回值数组
        /// </summary>
        /// <param name="stationStatus"></param>
        /// <returns></returns>
        public static Tuple<int, int> GetReturnBytesOff(string stationStatus)
        {
            var dic = new Dictionary<string, Tuple<int, int>>();
            #region 状态读取数组
            dic["P6-STATUS"] = new Tuple<int, int>(SystemConstant.PLC06_RETURNSTATUS_DB, SystemConstant.PLC06_RETURNSTATUS_ENDOFF);
            #endregion

            if (dic.TryGetValue(stationStatus, out Tuple<int, int> value))
                return value;
            return null;
        }

        /// <summary>
        /// 根据字符串数据获取相关DB数据的二元组
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static Tuple<int, int> GetBytesOff(string key)
        {
            var dic = new Dictionary<string, Tuple<int, int>>();
            #region 状态读取数组
            dic["P6-STATUS"] = new Tuple<int, int>(SystemConstant.PLC06_STATUS_DB, SystemConstant.PLC06_STATUS_ENDOFF);
            #endregion

            #region PLC01数据数组
            dic["P6-CCD"] = new Tuple<int, int>(SystemConstant.PLC06_CCD_DB, SystemConstant.PLC06_CCD_ENDOFF);
            dic["P6-WELD"] = new Tuple<int, int>(SystemConstant.PLC06_WELD_DB, SystemConstant.PLC06_WELD_ENDOFF);
            dic["P6-POINT"] = new Tuple<int, int>(SystemConstant.PLC06_POINT_DB, SystemConstant.PLC06_POINT_ENDOFF);
            #endregion

            if (dic.TryGetValue(key, out Tuple<int, int> value))
                return value;
            return null;
        }

        /// <summary>
        /// 根据PlcName与StationName获取工艺名称
        /// </summary>
        /// <param name="plcName"></param>
        /// <param name="StationName"></param>
        /// <returns></returns>
        public static string GetOperationNo(string plcName, string StationName)
        {
            var dic = new Dictionary<string, Dictionary<string, string>>();

            dic["P6"] = new Dictionary<string, string>
            {
                { SystemConstant.OP10,"WELD"},
                { SystemConstant.OP20,"WELD"},
                { SystemConstant.OP25,"WELDVISION"},
                { SystemConstant.OP30,"POINT"},
                { SystemConstant.OP40,"CCD"},
            };

            if (dic.TryGetValue(plcName, out Dictionary<string, string> operationDic))
            {
                if (operationDic.TryGetValue(StationName, out string value))
                    return value;
            }
            return null;
        }

        /// <summary>
        /// 根据工位获取字段数据
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static Dictionary<string, int> GetWeldOff(string station)
        {
            Dictionary<string, Dictionary<string, int>> dic = new Dictionary<string, Dictionary<string, int>>();

            dic[SystemConstant.OP10] = new Dictionary<string, int>()
            {
                { "Off",2},
                { "SeamNo",130},
                { "StartTime",132},
                { "EndTime",140},
                { "WeldI",148},
                { "WeldU",548},
                { "WireSpeed",948},
                { "GasFlow",1348},
                { "Job",0},
            };

            dic[SystemConstant.OP20] = new Dictionary<string, int>()
            {
                { "Off",2},
                { "SeamNo",6732},
                { "StartTime",6734},
                { "EndTime",6742},
                { "WeldI",6750},
                { "WeldU",7150},
                { "WireSpeed",7550},
                { "GasFlow",7950},
                { "Job",160},
            };

            if (dic.TryGetValue(station, out Dictionary<string, int> value))
                return value;
            return null;
        }

        /// <summary>
        /// 获取CCD数据偏移量
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static Dictionary<string, int> GetCCDOff(string station)
        {
            Dictionary<string, Dictionary<string, int>> dic = new Dictionary<string, Dictionary<string, int>>();

            dic[SystemConstant.OP40] = new Dictionary<string, int>()
            {
                {"Off", 22},
                {"Number", 130},
                {"Result", 162},
            };

            if (dic.TryGetValue(station, out Dictionary<string, int> value))
                return value;
            return null;
        }

        /// <summary>
        /// 判断是否是否为该程序管辖的线体
        /// </summary>
        /// <param name="material_id"></param>
        /// <returns></returns>
        public static bool IsExistLine(string material_id)
        {
            return true;
        }

        /// <summary>
        /// 根据物料编码获取PlcName
        /// </summary>
        /// <param name="material_id"></param>
        /// <returns></returns>
        public static List<string> GetPlcNameByMaterial(string material_id)
        {
            Dictionary<string, List<string>> dic = new Dictionary<string, List<string>>()
            {
                {"100101000086",new List<string>{ "P6"} },
                {"100101000085",new List<string>{ "C"} },
            };

            if (dic.TryGetValue(material_id, out List<string> plcName))
            {
                return plcName;
            }

            return null;
        }

        /// <summary>
        /// 根据工位号获取PlcName与下发索引
        /// </summary>
        /// <param name="station"></param>
        public static Tuple<string, int> GetPlcNameAndIndex(string station)
        {
            Dictionary<string, Tuple<string, int>> keyValuePairs = new Dictionary<string, Tuple<string, int>>();

            keyValuePairs[""] = new Tuple<string, int>("P6", 1);

            if (keyValuePairs.TryGetValue(station, out var value))
                return value;
            return null;
        }

        /// <summary>
        /// 根据工位获取对应工序号
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static string GetOperationId(string station)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>()
            {
                { SystemConstant.CLINCHOP10,"A075"},

                { SystemConstant.RIVETE_1,"A217"},
                { SystemConstant.RIVETE_2,"A077"},
                { SystemConstant.RIVETE_3,"A078"},
                { SystemConstant.RIVETE_4,"A220"},
                { SystemConstant.CLINCH_1,"A228"},
                { SystemConstant.OP10,"A236"},
                { SystemConstant.OP20,"A288"},
                { SystemConstant.OP25,"A147"},
                { SystemConstant.OP30,"A002"},
                { SystemConstant.OP40,"A059"},
            };

            if (dic.TryGetValue(station, out string value))
            {
                return value;
            }

            return "未映射";
        }

        /// <summary>
        /// 判断是否是最后一个工位
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static bool GetEndStation(string station)
        {
            List<string> strings = new List<string>()
            {
                SystemConstant.OP40,
            };

            if (strings.Contains(station))
                return true;
            return false;
        }

        /// <summary>
        /// 获取返回偏移映射
        /// </summary>
        /// <param name="plcName"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static int GetPartResultOff(string plcName, string name)
        {
            Dictionary<string, Dictionary<string, int>> dic = new Dictionary<string, Dictionary<string, int>>();

            dic["P1"] = new Dictionary<string, int>
            {
                { "Code1",1},
                { "Code2",2},
                { "Code3",3},
                { "Code4",4},
                { "Code5",5},
            };

            dic["P2"] = new Dictionary<string, int>
            {
                { "Code1",1},
                { "Code2",2},
                { "Code3",3},
                { "Code4",4},
                { "Code5",5},
            };

            dic["P3"] = new Dictionary<string, int>
            {
                { "Code1",1},
            };

            if (dic.TryGetValue(plcName, out Dictionary<string, int> value))
            {
                if (value.TryGetValue(name, out int off))
                    return off;
            }

            return 1000;
        }

        /// <summary>
        /// 根据工序获取对应生产的物料编号
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static string GetMaterialByStation(string station)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>()
            {
                
                { SystemConstant.CLINCH_1,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.RIVETE_1,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.RIVETE_2,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.RIVETE_3,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.RIVETE_4,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.OP10,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.OP20,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.OP25,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.OP30,SystemConstant.AUTO_P6_MATERIALID},
                { SystemConstant.OP40,SystemConstant.AUTO_P6_MATERIALID},

                { SystemConstant.CLINCHOP10,"100101000085"},
            };

            if(dic.TryGetValue(station, out string value))
                return value;

            return "";
        }

        /// <summary>
        /// 根据工位号获取上一工位的工位号
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static string GetLastStation(string station)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>()
            {
                { SystemConstant.OP20,SystemConstant.OP10},
                { SystemConstant.OP25,SystemConstant.OP20},
                { SystemConstant.OP30,SystemConstant.OP25},
                { SystemConstant.OP40,SystemConstant.OP30},
            };

            if (dic.TryGetValue(station, out string value))
            {
                return value;
            }

            return "";
        }

        public static (string errorMessage, string errorType) GetErrorMessage(int @byte, int sty)
        {
            Dictionary<string, (string, string)> dic = new Dictionary<string, (string, string)>();

            dic[$"{0}.{0}"] = ("PLC故障", "上游PLC关联故障");
            dic[$"{0}.{1}"] = ("PLC故障", "下游PLC关联故障");

            dic[$"{2}.{0}"] = ("机器人故障", "R33机器人故障");
            dic[$"{4}.{0}"] = ("机器人故障", "R34机器人故障");
            dic[$"{6}.{0}"] = ("机器人故障", "R35机器人故障");
            dic[$"{8}.{0}"] = ("机器人故障", "R36机器人故障");

            dic[$"{22}.{0}"] = ("左侧夹具故障", "OP10_JIG气缸报错");
            dic[$"{22}.{1}"] = ("左侧夹具故障", "OP20_JIG气缸报错");
            dic[$"{22}.{2}"] = ("左侧夹具故障", "OP25_JIG气缸报错");
            dic[$"{22}.{3}"] = ("左侧夹具故障", "OP30_JIG报错");
            dic[$"{22}.{4}"] = ("左侧夹具故障", "OP26_NG_JIG报错");
            dic[$"{22}.{5}"] = ("左侧夹具故障", "OP50_JIG报错");

            dic[$"{24}.{0}"] = ("左侧夹具传感器故障", "OP10_JIG_SEN传感器报错");
            dic[$"{24}.{1}"] = ("左侧夹具传感器故障", "OP20_JIG_SEN传感器报错");
            dic[$"{24}.{2}"] = ("左侧夹具传感器故障", "OP25_JIG_SEN报错");
            dic[$"{24}.{3}"] = ("左侧夹具传感器故障", "OP30_JIG_SEN报错");
            dic[$"{24}.{4}"] = ("左侧夹具传感器故障", "OP26_NG_JIG_SEN报错");
            dic[$"{24}.{5}"] = ("左侧夹具传感器故障", "OP50_JIG_SEN报错");

            dic[$"{26}.{0}"] = ("电机故障", "OP40皮带机电机报错");

            dic[$"{28}.{0}"] = ("安全门故障", "PLC6_SD1安全门打开");
            dic[$"{28}.{1}"] = ("安全门故障", "PLC6_SD2安全门打开");

            dic[$"{30}.{0}"] = ("光栅故障", "OP10光栅被闯入");
            dic[$"{30}.{1}"] = ("光栅故障", "OP20光栅被闯入");
            dic[$"{30}.{2}"] = ("光栅故障", "OP25区域隔离光栅被闯入");
            dic[$"{30}.{3}"] = ("光栅故障", "OP50光栅被闯入");

            dic[$"{32}.{0}"] = ("急停故障", "HMI1急停");
            dic[$"{32}.{1}"] = ("急停故障", "HMI2急停");
            dic[$"{32}.{2}"] = ("急停故障", "HMI3急停");
            dic[$"{32}.{3}"] = ("急停故障", "OP10-OB急停");
            dic[$"{32}.{4}"] = ("急停故障", "OP20-OB急停");
            dic[$"{32}.{5}"] = ("急停故障", "OP26_NG-OB急停");
            dic[$"{32}.{6}"] = ("急停故障", "OP50-OB急停");
            dic[$"{32}.{7}"] = ("急停故障", "OP40皮带机-OB急停");
            dic[$"{33}.{0}"] = ("急停故障", "SD1急停");
            dic[$"{33}.{1}"] = ("急停故障", "SD2急停");
            dic[$"{33}.{2}"] = ("急停故障", "R33机器人急停");
            dic[$"{33}.{3}"] = ("急停故障", "R34机器人急停");
            dic[$"{33}.{4}"] = ("急停故障", "R35机器人急停");
            dic[$"{33}.{5}"] = ("急停故障", "R36机器人急停");

            dic[$"{36}.{0}"] = ("通讯故障", "CPU通讯故障");

            dic[$"{37}.{2}"] = ("通讯故障", "HMI1通讯故障");
            dic[$"{37}.{3}"] = ("通讯故障", "HMI2通讯故障");
            dic[$"{37}.{4}"] = ("通讯故障", "HMI3通讯故障");

            dic[$"{38}.{4}"] = ("通讯故障", "MCP-ET200SP通讯故障");
            dic[$"{38}.{5}"] = ("通讯故障", "OP10_AJ1-ET200SP通讯故障");
            dic[$"{38}.{6}"] = ("通讯故障", "OP20_AJ2-ET200SP通讯故障");

            dic[$"{41}.{0}"] = ("通讯故障", "OP10_SYS_BK01通讯报警");
            dic[$"{41}.{1}"] = ("通讯故障", "OP10_SYS_BK02通讯报警");
            dic[$"{41}.{2}"] = ("通讯故障", "OP20_SYS_BK01通讯报警");
            dic[$"{41}.{3}"] = ("通讯故障", "OP20_SYS_BK02通讯报警");
            dic[$"{41}.{4}"] = ("通讯故障", "OP25_AF25_BK01通讯报警");
            dic[$"{41}.{5}"] = ("通讯故障", "OP25_AJ25_BK01通讯报警");
            dic[$"{41}.{6}"] = ("通讯故障", "OP26_NG_BK01通讯报警");
            dic[$"{41}.{7}"] = ("通讯故障", "OP40_AF4_BK01通讯报警");

            dic[$"{48}.{3}"] = ("通讯故障", "OP10-AJ1-PM通讯故障");
            dic[$"{48}.{4}"] = ("通讯故障", "OP20-AJ2-PM通讯故障");
            dic[$"{48}.{5}"] = ("通讯故障", "OP25-AJ25-PM通讯故障");

            dic[$"{51}.{0}"] = ("通讯故障", "R33通讯故障");
            dic[$"{51}.{1}"] = ("通讯故障", "R34通讯故障");
            dic[$"{51}.{2}"] = ("通讯故障", "R35通讯故障");
            dic[$"{51}.{3}"] = ("通讯故障", "R36通讯故障");

            dic[$"{53}.{4}"] = ("通讯故障", "OP10扫码枪通讯故障");
            dic[$"{53}.{5}"] = ("通讯故障", "OP20扫码枪通讯故障");
            dic[$"{53}.{6}"] = ("通讯故障", "返修区扫码枪通讯故障");
            dic[$"{53}.{7}"] = ("通讯故障", "打标台扫码枪通讯故障");

            dic[$"{54}.{0}"] = ("通讯故障", "固定扫码枪N_L20通讯故障");
            dic[$"{54}.{5}"] = ("通讯故障", "电能表通讯故障");

            dic[$"{56}.{0}"] = ("通讯故障", "OP30打码机通讯故障");

            dic[$"{57}.{1}"] = ("通讯故障", "防漏检测相机通讯故障");
            dic[$"{57}.{2}"] = ("通讯故障", "焊缝检测相机通讯故障");
            dic[$"{57}.{3}"] = ("通讯故障", "维修区ISV通讯故障");
            dic[$"{57}.{4}"] = ("通讯故障", "返修区视觉柜通讯故障");

            dic[$"{61}.{0}"] = ("通讯故障", "R33弧焊机通讯故障");
            dic[$"{61}.{1}"] = ("通讯故障", "R34阀导通讯故障");
            dic[$"{61}.{2}"] = ("通讯故障", "R36阀导通讯故障");
            dic[$"{61}.{3}"] = ("通讯故障", "R34BK01通讯故障");
            dic[$"{61}.{4}"] = ("通讯故障", "R36BK01通讯故障");




            if (dic.TryGetValue($"{@byte}.{sty}", out var value))
            {
                return value;
            }

            return ("","");
        }

        /// <summary>
        /// 判断是否首工序
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public static bool GetStartStation(string station)
        {
            List<string> strings = new List<string>()
         {
             "S01R",
             SystemConstant.CLINCHOP10,
    
         };

            if (strings.Contains(station))
            {
                return true;
            }

            return false;
        }
    }
}